home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / ircii2-6.zip / SRC\IRCII-2.6\SOURCE\CRYPT.C < prev    next >
C/C++ Source or Header  |  1994-12-29  |  7KB  |  362 lines

  1. /*
  2.  * crypt.c: handles some encryption of messages stuff. 
  3.  *
  4.  * Written By Michael Sandrof
  5.  *
  6.  * Copyright(c) 1990 
  7.  *
  8.  * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT 
  9.  */
  10.  
  11. #ifndef lint
  12. static    char    rcsid[] = "@(#)$Id: crypt.c,v 1.15 1994/10/09 06:39:35 mrg Stab $";
  13. #endif
  14.  
  15. #include "irc.h"
  16. #include "crypt.h"
  17. #include "vars.h"
  18. #include "ircaux.h"
  19. #include "list.h"
  20. #include "ctcp.h"
  21. #include "output.h"
  22.  
  23. #define CRYPT_BUFFER_SIZE (IRCD_BUFFER_SIZE - 50)    /* Make this less than
  24.                              * the trasmittable
  25.                              * buffer */
  26. /*
  27.  * Crypt: the crypt list structure,  consists of the nickname, and the
  28.  * encryption key 
  29.  */
  30. typedef struct    CryptStru
  31. {
  32.     struct    CryptStru *next;
  33.     char    *nick;
  34.     char    *key;
  35. }    Crypt;
  36.  
  37. /* crypt_list: the list of nicknames and encryption keys */
  38. static    Crypt    *crypt_list = (Crypt *) 0;
  39.  
  40. /*
  41.  * add_to_crypt: adds the nickname and key pair to the crypt_list.  If the
  42.  * nickname is already in the list, then the key is changed the the supplied
  43.  * key. 
  44.  */
  45. static    void
  46. add_to_crypt(nick, key)
  47.     char    *nick;
  48.     char    *key;
  49. {
  50.     Crypt    *new;
  51.  
  52.     if ((new = (Crypt *) remove_from_list(&crypt_list, nick)) != NULL)
  53.     {
  54.         new_free(&(new->nick));
  55.         new_free(&(new->key));
  56.         new_free(&new);
  57.     }
  58.     new = (Crypt *) new_malloc(sizeof(Crypt));
  59.     new->nick = (char *) 0;
  60.     new->key = (char *) 0;
  61.     malloc_strcpy(&(new->nick), nick);
  62.     malloc_strcpy(&(new->key), key);
  63.     /* upper(new->nick); */
  64.     add_to_list(&crypt_list, new);
  65. }
  66.  
  67. /*
  68.  * remove_crypt: removes the given nickname from the crypt_list, returning 0
  69.  * if successful, and 1 if not (because the nickname wasn't in the list) 
  70.  */
  71. static    int
  72. remove_crypt(nick)
  73.     char    *nick;
  74. {
  75.     Crypt    *tmp;
  76.  
  77.     if ((tmp = (Crypt *) list_lookup(&crypt_list, nick, !USE_WILDCARDS,
  78.             REMOVE_FROM_LIST)) != NULL)
  79.     {
  80.         new_free(&(tmp->nick));
  81.         new_free(&(tmp->key));
  82.         new_free(&tmp);
  83.         return (0);
  84.     }
  85.     return (1);
  86. }
  87.  
  88. /*
  89.  * is_crypted: looks up nick in the crypt_list and returns the encryption key
  90.  * if found in the list.  If not found in the crypt_list, null is returned. 
  91.  */
  92. char    *
  93. is_crypted(nick)
  94.     char    *nick;
  95. {
  96.     Crypt    *tmp;
  97.  
  98.     if (!crypt_list)
  99.         return NULL;
  100.     if ((tmp = (Crypt *) list_lookup(&crypt_list, nick,
  101.             !USE_WILDCARDS, !REMOVE_FROM_LIST)) != NULL)
  102.         return (tmp->key);
  103.     return NULL;
  104. }
  105.  
  106. /*
  107.  * encrypt_cmd: the ENCRYPT command.  Adds the given nickname and key to the
  108.  * encrypt list, or removes it, or list the list, you know. 
  109.  */
  110. /*ARGSUSED*/
  111. void
  112. encrypt_cmd(command, args)
  113.     char    *command,
  114.         *args;
  115. {
  116.     char    *nick,
  117.     *key;
  118.  
  119.     if ((nick = next_arg(args, &args)) != NULL)
  120.     {
  121.         if ((key = next_arg(args, &args)) != NULL)
  122.         {
  123.             add_to_crypt(nick, key);
  124.             say("%s added to the crypt with key %s", nick, key);
  125.         }
  126.         else
  127.         {
  128.             if (remove_crypt(nick))
  129.                 say("No such nickname in the crypt: %s", nick);
  130.             else
  131.                 say("%s removed from the crypt", nick);
  132.         }
  133.     }
  134.     else
  135.     {
  136.         if (crypt_list)
  137.         {
  138.             Crypt    *tmp;
  139.  
  140.             say("The crypt:");
  141.             for (tmp = crypt_list; tmp; tmp = tmp->next)
  142.                 put_it("%s with key %s", tmp->nick, tmp->key);
  143.         }
  144.         else
  145.             say("The crypt is empty");
  146.     }
  147. }
  148.  
  149. static    void
  150. encrypt_str(str, len, key)
  151.     char    *str,
  152.         *key;
  153.     int    len;
  154. {
  155.     int    key_len,
  156.     key_pos,
  157.     i;
  158.     char    mix,
  159.     tmp;
  160.  
  161.     key_len = strlen(key);
  162.     key_pos = 0;
  163.     /*    mix = key[key_len-1]; */
  164.     mix = 0;
  165.     for (i = 0; i < len; i++)
  166.     {
  167.         tmp = str[i];
  168.         str[i] = mix ^ tmp ^ key[key_pos];
  169.         mix ^= tmp;
  170.         key_pos = (key_pos + 1) % key_len;
  171.     }
  172.     str[i] = (char) 0;
  173. }
  174.  
  175. static    void
  176. decrypt(str, len, key)
  177.     char    *str,
  178.         *key;
  179.     int    len;
  180. {
  181.     int    key_len,
  182.         key_pos,
  183.         i;
  184.     char    mix,
  185.         tmp;
  186.  
  187.     key_len = strlen(key);
  188.     key_pos = 0;
  189.     /*    mix = key[key_len-1]; */
  190.     mix = 0;
  191.     for (i = 0; i < len; i++)
  192.     {
  193.         tmp = mix ^ str[i] ^ key[key_pos];
  194.         str[i] = tmp;
  195.         mix ^= tmp;
  196.         key_pos = (key_pos + 1) % key_len;
  197.     }
  198.     str[i] = (char) 0;
  199. }
  200.  
  201. static    char    *
  202. do_crypt(str, key, flag)
  203.     char    *str,
  204.         *key;
  205.     int    flag;
  206. {
  207.     int    in[2],
  208.     out[2],
  209.     c;
  210.     char    buffer[CRYPT_BUFFER_SIZE + 1];
  211.     char    *ptr = (char *) 0,
  212.         *encrypt_program;
  213.  
  214. #ifndef _Windows
  215.     encrypt_program = get_string_var(ENCRYPT_PROGRAM_VAR);
  216.     if (encrypt_program)
  217.     {
  218. #ifdef DAEMON_UID
  219.         if (DAEMON_UID == getuid())
  220.         {
  221.             say("ENCRYPT_PROGRAM not available from daemon mode");
  222.             return (char *) 0;
  223.         }
  224. #endif
  225.         in[0] = in[1] = -1;
  226.         out[0] = out[1] = -1;
  227.         if (access(encrypt_program, X_OK))
  228.         {
  229.             say("Unable to execute encryption program: %s", encrypt_program);
  230.             return ((char *) 0);
  231.         }
  232.         if (!flag)
  233.         {
  234.             c = strlen(str);
  235.             ptr = ctcp_unquote_it(str, &c);
  236.         }
  237.         else
  238.             malloc_strcpy(&ptr, str);
  239.         if (pipe(in) || pipe(out))
  240.         {
  241.             say("Unable to start encryption process: %s", strerror(errno));
  242.             if (in[0] != -1)
  243.             {
  244.                 close(in[0]);
  245.                 close(in[1]);
  246.             }
  247.             if (out[0] != -1)
  248.             {
  249.                 close(out[0]);
  250.                 close(out[1]);
  251.             }
  252.         }
  253.         switch (fork())
  254.         {
  255.         case -1:
  256.             say("Unable to start encryption process: %s", strerror(errno));
  257.             return ((char *) 0);
  258.         case 0:
  259.             MY_SIGNAL(SIGINT, SIG_IGN, 0);
  260.             dup2(out[1], 1);
  261.             dup2(in[0], 0);
  262.             close(out[0]);
  263.             close(in[1]);
  264.             setuid(getuid());
  265.             setgid(getgid());
  266.             execl(encrypt_program, encrypt_program, key, NULL);
  267.             exit(0);
  268.         default:
  269.             close(out[1]);
  270.             close(in[0]);
  271.             write(in[1], ptr, strlen(ptr));
  272.             close(in[1]);
  273.             c = read(out[0], buffer, CRYPT_BUFFER_SIZE);
  274.             buffer[c] = (char) 0;
  275.             close(out[0]);
  276.             break;
  277.         }
  278.         new_free(&ptr);
  279.         if (flag)
  280.             ptr = ctcp_quote_it(buffer, strlen(buffer));
  281.         else
  282.             malloc_strcpy(&ptr, buffer);
  283.     }
  284.     else
  285. #endif /* _Windows */
  286.     {
  287.         c = strlen(str);
  288.         if (flag)
  289.         {
  290.             encrypt_str(str, c, key);
  291.             ptr = ctcp_quote_it(str, c);
  292.         }
  293.         else
  294.         {
  295.             ptr = ctcp_unquote_it(str, &c);
  296.             decrypt(ptr, c, key);
  297.         }
  298.     }
  299.     return (ptr);
  300. }
  301.  
  302. /*
  303.  * crypt_msg: Executes the encryption program on the given string with the
  304.  * given key.  If flag is true, the string is encrypted and the returned
  305.  * string is ready to be sent over irc.  If flag is false, the string is
  306.  * decrypted and the returned string should be readable 
  307.  */
  308. char    *
  309. crypt_msg(str, key, flag)
  310.     char    *str,
  311.         *key;
  312.     int    flag;
  313. {
  314.     static    char    buffer[CRYPT_BUFFER_SIZE + 1];
  315.     char    thing[6];
  316.     char    *ptr,
  317.         *rest;
  318.     int    on = 1;
  319.  
  320.     if (flag)
  321.     {
  322.         sprintf(thing, "%cSED ", CTCP_DELIM_CHAR);
  323.         *buffer = (char) 0;
  324.         while ((rest = index(str, '\005')) != NULL)
  325.         {
  326.             *(rest++) = (char) 0;
  327.             if (on && *str && (ptr = do_crypt(str, key, flag)))
  328.             {
  329.                 strmcat(buffer, thing, CRYPT_BUFFER_SIZE);
  330.                 strmcat(buffer, ptr, CRYPT_BUFFER_SIZE);
  331.                 strmcat(buffer, CTCP_DELIM_STR, CRYPT_BUFFER_SIZE);
  332.                 new_free(&ptr);
  333.             }
  334.             else
  335.                 strmcat(buffer, str, CRYPT_BUFFER_SIZE);
  336.             on = !on;
  337.             str = rest;
  338.         }
  339.         if (on && (ptr = do_crypt(str, key, flag)))
  340.         {
  341.             strmcat(buffer, thing, CRYPT_BUFFER_SIZE);
  342.             strmcat(buffer, ptr, CRYPT_BUFFER_SIZE);
  343.             strmcat(buffer, CTCP_DELIM_STR, CRYPT_BUFFER_SIZE);
  344.             new_free(&ptr);
  345.         }
  346.         else
  347.             strmcat(buffer, str, CRYPT_BUFFER_SIZE);
  348.     }
  349.     else
  350.     {
  351.         if ((ptr = do_crypt(str, key, flag)) != NULL)
  352.         {
  353.             strmcpy(buffer, ptr, CRYPT_BUFFER_SIZE);
  354.             new_free(&ptr);
  355.         }
  356.         else
  357.             strmcat(buffer, str, CRYPT_BUFFER_SIZE);
  358.     }
  359.     return (buffer);
  360. }
  361.  
  362.